-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix deadlock during prevote migration process #42
fix deadlock during prevote migration process #42
Conversation
tests/cases/test_raft.rs
Outdated
// n1.state == Leader | ||
// n2.state == Follower | ||
// n3.state == Candidate | ||
if nt.peers[&1].state != StateRole::Leader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use assert_eq here
tests/cases/test_raft.rs
Outdated
// n1.Term == 2 | ||
// n2.Term == 2 | ||
// n3.Term == 4 | ||
if nt.peers[&1].term != 2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
tests/cases/test_raft.rs
Outdated
// n2 is follower with term 2 | ||
// n3 is pre-candidate with term 4, and less log | ||
|
||
// simulate leader down |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please format your code with rustfmt nightly version 0.3.4
src/raft.rs
Outdated
@@ -955,6 +955,27 @@ impl<T: Storage> Raft<T> { | |||
// will not create disruptive term increases | |||
let to_send = new_message(m.get_from(), MessageType::MsgAppendResponse, None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify what you'd like to see?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe need to copy from etcd?
tests/cases/test_raft.rs
Outdated
n2.become_follower(1, INVALID_ID); | ||
n3.become_follower(1, INVALID_ID); | ||
|
||
// We intentionally do not enable pre_vote for n3, this is done so in order |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment should be put to L3854.
tests/cases/test_raft.rs
Outdated
let mut e = Entry::new(); | ||
e.set_data(b"some data".to_vec()); | ||
nt.send(vec![ | ||
new_message_with_entries(1, 1, MessageType::MsgPropose, vec![e]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use new_message(1, 1, MessageType::MsgPropose, 1)
.
tests/cases/test_raft.rs
Outdated
// n2.state == Follower | ||
// n3.state == Candidate | ||
assert_eq!(nt.peers[&1].state, | ||
StateRole::Leader, "node 1 state: {:?}, want {:?}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to customize the message as assert_eq
did it for you already.
tests/cases/test_raft.rs
Outdated
// version cluster with replicas with pre_vote enabled, and replicas without. | ||
let mut nt = Network::new(vec![Some(n1), Some(n2), Some(n3)]); | ||
|
||
nt.peers.get_mut(&2).unwrap().pre_vote = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use new_test_raft_with_pre_vote
.
tests/cases/test_raft.rs
Outdated
fn test_prevote_migration_can_complete_election() { | ||
let mut nt = new_prevote_migration_cluster(); | ||
|
||
// n1 is leader with term 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the comment to L3923.
tests/cases/test_raft.rs
Outdated
|
||
// Do we have a leader? | ||
// assert_eq!(nt.peers[&2].state, StateRole::Leader ) | ||
if nt.peers[&2].state != StateRole::Leader && nt.peers[&3].state != StateRole::Follower { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use assert!
instead.
src/raft.rs
Outdated
@@ -955,6 +955,27 @@ impl<T: Storage> Raft<T> { | |||
// will not create disruptive term increases | |||
let to_send = new_message(m.get_from(), MessageType::MsgAppendResponse, None); | |||
self.send(to_send); | |||
} else if m.get_msg_type() == MessageType::MsgRequestPreVote { | |||
// Before pre_vote enable, there may have candidate with higher term, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment is confusing. I thought candidate
here refers to the one who sends prevote request. Turns out it refers to the receiver. Could you make it better?
@Hoverbear sorry for a delayed commit, I totally forgot this thread. |
9f9cfb4
to
2c24c57
Compare
@BusyJay Can you give this another look regarding the feedback you gave? |
PTAL @hicqu |
tests/cases/test_raft.rs
Outdated
nt.send(vec![new_message(2, 2, MessageType::MsgHup, 0)]); | ||
|
||
// Do we have a leader? | ||
assert_eq!(nt.peers[&2].state, StateRole::Leader); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we guarantee the leader can always be elected? It is different from https://github.com/coreos/etcd/pull/8525/files#diff-ad12a9c9b66e1507ca04edc74b4b1e8aR3386
Rest LGTM |
any update @csmoe? |
tests/cases/test_raft.rs
Outdated
nt.send(vec![new_message(2, 2, MessageType::MsgHup, 0)]); | ||
|
||
// Do we have a leader? | ||
assert_eq!((nt.peers[&2].state, nt.peers[&3].state), (StateRole::Leader, StateRole::Follower)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is still different from https://github.com/coreos/etcd/pull/8525/files?utf8=%E2%9C%93&diff=unified#diff-ad12a9c9b66e1507ca04edc74b4b1e8aR3386.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, I don't know how to fix this since I thought this tuple comparsion might work like &&
here. could you give me some tips?
Will simulating leader down(nt.solate(1)
) before new election guarantee that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in your test, you require 2 must be the leader, and 3 must be the follower. But in the etcd test, if 2 is the leader, 3 can be not the follower.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, thank you, I made a logic mistake here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rest LGTM
src/raft.rs
Outdated
@@ -224,7 +224,7 @@ pub struct Raft<T: Storage> { | |||
heartbeat_elapsed: usize, | |||
|
|||
pub check_quorum: bool, | |||
pre_vote: bool, | |||
pub pre_vote: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a doc hidden attribute.
tests/cases/test_raft.rs
Outdated
nt.isolate(1); | ||
|
||
// Call for elections from both n2 and n3. | ||
nt.send(vec![new_message(2, 2, MessageType::MsgHup, 0)]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order is important, although it won't affect the test result (yet).
tests/cases/test_raft.rs
Outdated
nt.send(vec![new_message(3, 3, MessageType::MsgHup, 0)]); | ||
|
||
assert_eq!(nt.peers[&1].state, | ||
StateRole::Leader, "node 1 state: {:?}, want {:?}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug message is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
PTAL @Hoverbear |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. 👍
Please run |
fa74996
to
c74e0af
Compare
@Hoverbear The current rustfmt in CI is stable-ver, but:
So rustfmt config might need changes. |
Ping @Hoverbear |
Opened #62 to reflect the |
Fixes #20